package wxcloud

import (
	"context"
	"encoding/json"
	"fmt"
	"strings"
	"time"

	"github.com/mars/internal/admin/core/domain"
	"github.com/mars/internal/pkg/wxcloud"
)

const (
	productCollection = "product" // 商品集合名称
)

type ProductGatewayImpl struct {
	wxcloud *wxcloud.WxCloudClient
}

var _ domain.ProductGateway = (*ProductGatewayImpl)(nil)

func newProductGatewayImpl(wxcloud *wxcloud.WxCloudClient) *ProductGatewayImpl {
	return &ProductGatewayImpl{wxcloud: wxcloud}
}

// GetProductList 获取商品列表
func (p *ProductGatewayImpl) GetProductList(ctx context.Context, params domain.ProductQueryParams) ([]domain.Product, int64, error) {
	// 构建查询语句
	queryBuilder := wxcloud.NewQueryBuilder(productCollection)

	// 添加类型筛选
	if params.Type != "" {
		queryBuilder = queryBuilder.Where("type", string(params.Type))
	}

	// 添加状态筛选
	if params.Status != "" {
		queryBuilder = queryBuilder.Where("status", string(params.Status))
	}

	// 添加关键字搜索
	if params.Keyword != "" {
		queryBuilder = queryBuilder.Where("name", params.Keyword)
	}

	// 添加排序
	sortField := "sort"
	sortOrder := "asc"
	if params.Sort != "" {
		sortField = params.Sort
	}
	if params.Order == "desc" {
		sortOrder = "desc"
	}
	queryBuilder = queryBuilder.OrderBy(sortField, sortOrder)

	// 添加分页
	pageSize := 20
	if params.PageSize > 0 {
		pageSize = params.PageSize
	}
	queryBuilder = queryBuilder.Limit(pageSize)

	if params.Page > 0 {
		offset := (params.Page - 1) * pageSize
		queryBuilder = queryBuilder.Skip(offset)
	}

	query := queryBuilder.BuildQueryString()

	// 执行查询
	resp, err := p.wxcloud.DatabaseQuery(ctx, p.wxcloud.EnvId(), query)
	if err != nil {
		return nil, 0, fmt.Errorf("failed to query products: %w", err)
	}

	// 转换数据
	products := make([]domain.Product, 0, len(resp.Data))
	for _, item := range resp.Data {
		var product domain.Product
		if err := json.Unmarshal([]byte(item), &product); err != nil {
			return nil, 0, err
		}
		if strings.HasPrefix(product.Image, "cloud:") {
			downloadURL, err := p.wxcloud.GetDownloadURL(ctx, product.Image, 600)
			if err != nil {
				return nil, 0, err
			}
			product.Image = downloadURL
		}

		products = append(products, product)
	}

	return products, int64(resp.Pager.Total), nil
}

// GetProduct 根据ID获取商品详情
func (p *ProductGatewayImpl) GetProduct(ctx context.Context, productID string) (*domain.Product, error) {
	query := wxcloud.NewQueryBuilder(productCollection).
		Where("_id", productID).
		Limit(1).
		BuildQueryString()

	resp, err := p.wxcloud.DatabaseQuery(ctx, p.wxcloud.EnvId(), query)
	if err != nil {
		return nil, fmt.Errorf("failed to query product: %w", err)
	}

	if len(resp.Data) == 0 {
		return nil, fmt.Errorf("product not found with id: %s", productID)
	}

	var product domain.Product
	if err := json.Unmarshal([]byte(resp.Data[0]), &product); err != nil {
		return nil, err
	}

	if strings.HasPrefix(product.Image, "cloud:") {
		downloadURL, err := p.wxcloud.GetDownloadURL(ctx, product.Image, 600)
		if err != nil {
			return nil, err
		}
		product.Image = downloadURL
	}

	images := make([]string, 0, len(product.Images))
	for _, image := range product.Images {
		if strings.HasPrefix(image, "cloud:") {
			downloadURL, err := p.wxcloud.GetDownloadURL(ctx, image, 600)
			if err != nil {
				return nil, err
			}
			images = append(images, downloadURL)
		} else {
			images = append(images, image)
		}
	}
	product.Images = images

	return &product, nil
}

// CreateProduct 创建商品
func (p *ProductGatewayImpl) CreateProduct(ctx context.Context, product *domain.Product) error {
	now := time.Now().Unix()
	product.CreateTime = now
	product.UpdateTime = now

	// 设置默认值
	if product.Status == "" {
		product.Status = domain.ProductStatusActive
	}

	query := wxcloud.BuildAddString(productCollection, product)

	_, err := p.wxcloud.DatabaseAdd(ctx, p.wxcloud.EnvId(), query)
	if err != nil {
		return fmt.Errorf("failed to create product: %w", err)
	}

	return nil
}

// UpdateProduct 更新商品信息
func (p *ProductGatewayImpl) UpdateProduct(ctx context.Context, productID string, product *domain.Product) error {
	where := map[string]interface{}{
		"_id": productID,
	}

	updateData := make(map[string]interface{})
	updateData["updateTime"] = time.Now().Unix()

	// 只更新非空字段
	if product.Name != "" {
		updateData["name"] = product.Name
	}
	if product.Description != "" {
		updateData["description"] = product.Description
	}
	if product.Detail != "" {
		updateData["detail"] = product.Detail
	}
	if product.Price > 0 {
		updateData["price"] = product.Price
	}
	if product.Image != "" {
		updateData["image"] = product.Image
	}
	if len(product.Images) > 0 {
		updateData["images"] = product.Images
	}
	if product.Status != "" {
		updateData["status"] = string(product.Status)
	}
	if product.Sort != 0 {
		updateData["sort"] = product.Sort
	}
	if product.Stock != nil {
		updateData["stock"] = *product.Stock
	}
	if product.TicketType != "" {
		updateData["ticketType"] = product.TicketType
	}
	if product.VipDiscount != nil {
		updateData["vipDiscount"] = product.VipDiscount
	}
	if len(product.Specifications) > 0 {
		updateData["specifications"] = product.Specifications
	}

	if len(updateData) == 1 {
		return fmt.Errorf("no fields to update")
	}

	query := wxcloud.BuildUpdateString(productCollection, where, updateData)

	matched, modified, err := p.wxcloud.DatabaseUpdate(ctx, p.wxcloud.EnvId(), query)
	if err != nil {
		return fmt.Errorf("failed to update product: %w", err)
	}

	if matched == 0 {
		return fmt.Errorf("product not found with id: %s", productID)
	}

	if modified == 0 {
		return fmt.Errorf("product update failed, no records modified")
	}

	return nil
}

// DeleteProduct 删除商品（软删除）
func (p *ProductGatewayImpl) DeleteProduct(ctx context.Context, productID string) error {
	return p.UpdateProductStatus(ctx, productID, domain.ProductStatusInactive)
}

// GetProductsByType 根据类型获取商品列表
func (p *ProductGatewayImpl) GetProductsByType(ctx context.Context, productType domain.ProductType) ([]domain.Product, error) {
	query := wxcloud.NewQueryBuilder(productCollection).
		Where("type", string(productType)).
		OrderBy("sort", "asc").
		Limit(1000).
		BuildQueryString()

	resp, err := p.wxcloud.DatabaseQuery(ctx, p.wxcloud.EnvId(), query)
	if err != nil {
		return nil, fmt.Errorf("failed to query products by type: %w", err)
	}

	products := make([]domain.Product, 0, len(resp.Data))
	for _, item := range resp.Data {
		var product domain.Product
		if err := json.Unmarshal([]byte(item), &product); err == nil {
			products = append(products, product)
		} else {
			return nil, err
		}
	}

	return products, nil
}

// GetProductsByStatus 根据状态获取商品列表
func (p *ProductGatewayImpl) GetProductsByStatus(ctx context.Context, status domain.ProductStatus) ([]domain.Product, error) {
	query := wxcloud.NewQueryBuilder(productCollection).
		Where("status", string(status)).
		OrderBy("sort", "asc").
		Limit(1000).
		BuildQueryString()

	resp, err := p.wxcloud.DatabaseQuery(ctx, p.wxcloud.EnvId(), query)
	if err != nil {
		return nil, fmt.Errorf("failed to query products by status: %w", err)
	}

	products := make([]domain.Product, 0, len(resp.Data))
	for _, item := range resp.Data {
		var product domain.Product
		if err := json.Unmarshal([]byte(item), &product); err == nil {
			products = append(products, product)
		} else {
			return nil, err
		}
	}

	return products, nil
}

// UpdateProductStatus 更新商品状态
func (p *ProductGatewayImpl) UpdateProductStatus(ctx context.Context, productID string, status domain.ProductStatus) error {
	where := map[string]interface{}{
		"_id": productID,
	}

	updateData := map[string]interface{}{
		"status":     string(status),
		"updateTime": time.Now().Unix(),
	}

	query := wxcloud.BuildUpdateString(productCollection, where, updateData)

	matched, modified, err := p.wxcloud.DatabaseUpdate(ctx, p.wxcloud.EnvId(), query)
	if err != nil {
		return fmt.Errorf("failed to update product status: %w", err)
	}

	if matched == 0 {
		return fmt.Errorf("product not found with id: %s", productID)
	}

	if modified == 0 {
		return fmt.Errorf("product status update failed, no records modified")
	}

	return nil
}

// UpdateProductStock 更新商品库存
func (p *ProductGatewayImpl) UpdateProductStock(ctx context.Context, productID string, stock int) error {
	where := map[string]interface{}{
		"_id": productID,
	}

	updateData := map[string]interface{}{
		"stock":      stock,
		"updateTime": time.Now().Unix(),
	}

	query := wxcloud.BuildUpdateString(productCollection, where, updateData)

	matched, modified, err := p.wxcloud.DatabaseUpdate(ctx, p.wxcloud.EnvId(), query)
	if err != nil {
		return fmt.Errorf("failed to update product stock: %w", err)
	}

	if matched == 0 {
		return fmt.Errorf("product not found with id: %s", productID)
	}

	if modified == 0 {
		return fmt.Errorf("product stock update failed, no records modified")
	}

	return nil
}

// GetProductStats 获取商品统计信息
func (p *ProductGatewayImpl) GetProductStats(ctx context.Context) (*domain.ProductStats, error) {
	// 获取所有商品进行统计（简化实现）
	query := wxcloud.NewQueryBuilder(productCollection).
		Limit(10000).
		BuildQueryString()

	resp, err := p.wxcloud.DatabaseQuery(ctx, p.wxcloud.EnvId(), query)
	if err != nil {
		return nil, fmt.Errorf("failed to query products for stats: %w", err)
	}

	stats := &domain.ProductStats{}
	stats.Total = int64(len(resp.Data))

	// 统计各种类型和状态的商品数量
	for _, item := range resp.Data {
		var product domain.Product
		if err := json.Unmarshal([]byte(item), &product); err == nil {
			switch product.Type {
			case domain.ProductTypeVIP:
				stats.VipCount++
			case domain.ProductTypeTicket:
				stats.TicketCount++
			case domain.ProductTypePhysical:
				stats.PhysicalCount++
			}

			switch product.Status {
			case domain.ProductStatusActive:
				stats.ActiveCount++
			case domain.ProductStatusInactive:
				stats.InactiveCount++
			}
		}
	}

	return stats, nil
}

// GenerateUploadUrls 生成商品图片上传链接
func (p *ProductGatewayImpl) GenerateUploadUrl(ctx context.Context, filename string) (*wxcloud.UploadFileResponse, error) {
	uploadResp, err := p.wxcloud.GetUploadURL(ctx, filename)
	if err != nil {
		return nil, fmt.Errorf("failed to generate upload url: %w", err)
	}
	return uploadResp, nil
}

// SearchProducts 搜索商品
func (p *ProductGatewayImpl) SearchProducts(ctx context.Context, keyword string) ([]domain.Product, error) {
	// 简化的搜索实现
	query := wxcloud.NewQueryBuilder(productCollection).
		Where("name", keyword).
		OrderBy("sort", "asc").
		Limit(100).
		BuildQueryString()

	resp, err := p.wxcloud.DatabaseQuery(ctx, p.wxcloud.EnvId(), query)
	if err != nil {
		return nil, fmt.Errorf("failed to search products: %w", err)
	}

	products := make([]domain.Product, 0, len(resp.Data))
	for _, item := range resp.Data {
		var product domain.Product
		if err := json.Unmarshal([]byte(item), &product); err == nil {
			products = append(products, product)
		} else {
			return nil, err
		}
	}

	return products, nil
}

// UploadFiles 直接上传文件到云存储
func (p *ProductGatewayImpl) UploadFile(ctx context.Context, uploadResp *wxcloud.UploadFileResponse, filePath string, data []byte) error {
	return p.wxcloud.UploadFile(ctx, uploadResp, filePath, data)
}
